package us.nchu.onlineJudger;

import cn.hutool.db.Entity;
import cn.hutool.db.SqlRunner;
import cn.hutool.setting.dialect.Props;
import org.apache.activemq.ActiveMQConnectionFactory;
import us.nchu.onlineJudger.bean.AbstractJudger;
import us.nchu.onlineJudger.bean.AbstractResult;
import us.nchu.onlineJudger.bean.MqMessage;
import us.nchu.onlineJudger.factory.AbstractFactory;
import us.nchu.onlineJudger.util.FactoryUtil;
import us.nchu.onlineJudger.util.JsonUtil;

import javax.jms.*;
import java.sql.SQLException;

public class JudgerMain {

    public static void main(String[] args) {
        // 读取配置文件
        Props props = new Props("activemq-config.properties");
        // 创建工厂
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                props.getStr("mq.user"), props.getStr("mq.password"),
                "tcp://" + props.getStr("mq.host") + ":" + props.getStr("mq.port"));

        Connection conn = null;
        Session session = null;
        Queue queue = null;
        MessageConsumer messageConsumer = null;
        try {
            // 创建连接
            conn = connectionFactory.createConnection();
            // 启动连接
            conn.start();
            // 创建会话 createSession(true, Session.AUTO_ACKNOWLEDGE); false 表示不开启事务
            // Session.AUTO_ACKNOWLEDGE 消息模式
            session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
            // 创建队列
            queue = session.createQueue(props.getStr("mq.queueName"));
            // 创建消息消费者
            messageConsumer = session.createConsumer(queue);
            // 注册消费消息监听
            messageConsumer.setMessageListener(new MessageListener() {

                @Override
                public void onMessage(Message message) {
                    try {
                        // 将消息队列中的信息转成MqMessage的对象
                        MqMessage mqMessage = JsonUtil.stringToAbstractMqMessage(((TextMessage) message).getText());

                        // 通过工厂模式创建相应语言的Judger对象
                        Props facProps = new Props("factory-config.properties");
                        AbstractFactory factory = FactoryUtil.getFactory(facProps.getStr("factory.judger." + mqMessage.getLanguage()));
                        AbstractJudger judger = factory.getInstance(mqMessage);

                        // 开始判题,判题结果存到result对象中
                        AbstractResult result = judger.doJudge();

                        // 更新数据库
                        SqlRunner runner = SqlRunner.create();
                        Entity setEntity = Entity.create("oj_judge_status").set("judge_status_code", result.getJudge_status_code())
                                .set("judge_status_result", result.getJudge_status_result())
                                .set("judge_status_time", result.getJudge_status_time())
                                .set("judge_status_memory", result.getJudge_status_memory())
                                .set("judge_status_message", result.getJudge_status_message());;

                        Entity whereEntity = Entity.create().set("judge_status_id", mqMessage.getJudgeStatusId());
                        runner.update(setEntity, whereEntity);

                    } catch (JMSException e) {
                        e.printStackTrace();
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                        System.out.println("cannot create factory, maybe you don't have factory in your properties");
                    } catch (SQLException e) {
                        e.printStackTrace();
                        System.out.println("cannot create update database");
                    }
                }
            });
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}
